﻿using AdvancedPoll.Models;
using AdvancedPoll.Services;
using AdvancedPoll.ViewModels;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Core.Contents.Controllers;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Security;
using Orchard.Settings;
using Orchard.UI.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.Mvc;

namespace AdvancedPoll.Controllers
{
    [ComVisible(false)]
    public class VoteController : Controller
    {
        private readonly IPollService _pollService;
        private readonly IOrchardServices _orchardServices;
        private readonly IVotingService _votingService;

        public VoteController(
            IPollService pollService,
            IOrchardServices orchardServices,
            IVotingService votingService)
        {
            _pollService = pollService;
            _orchardServices = orchardServices;
            _votingService = votingService;
            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        public ActionResult Index()
        {
            return View();
        }

        [AllowAnonymous]
        [HttpPost]
        public JsonResult Vote(int id, string fingerprint, Collection<string> votes)
        {
            var currentUser = _orchardServices.WorkContext.CurrentUser;
            string user = currentUser == null ? "Anonymous" : currentUser.UserName;
            var poll = _pollService.GetPoll(id);
            if (poll == null)
                return Json(new { success = false, error = "Poll doesn't exists!" });
            if (votes == null || votes.Count == 0)
                return Json(new { success = false, error = "You have to choose at least 1 option!" });
            if (votes.Count > poll.MaxVotes)
                return Json(new { success = false, error = "You have choosen too many option!" });
            var voteIds = votes.Select(v => int.Parse(v));
            var list = _pollService.GetChoices(id).Where(c => voteIds.Contains(c.Id));
            if (_votingService.CanVote(id, user, fingerprint))
            {
                _votingService.TryVote(id, user, fingerprint, list);
                return Json(new { success = true });
            }
            else
            {
                if (_pollService.IsPollClosed(id))
                    return Json(new { success = false, error = "This poll is closed!" });
                return Json(new { success = false, error = "You have already voted!" });
            }
        }

        [AllowAnonymous]
        [HttpGet]
        public JsonResult GetResult(int id)
        {
            var results = _pollService.GetPollWithResult(id);
            return Json(new
            {
                result = results.Choices.Select(r =>
                    new Object[] { r.Result.Count, 
                        String.Format("<span original-title='{0}' class='tickSpan'>{1}{2}</span>", 
                            r.Choice.Answer, 
                            r.Choice.Answer.Substring(0, 10 > r.Choice.Answer.Length ? r.Choice.Answer.Length : 10), 
                            10 > r.Choice.Answer.Length ? "" : "...") })
            }, JsonRequestBehavior.AllowGet);
        }

        [AllowAnonymous]
        [HttpPost]
        public JsonResult CanVote(int id, string fingerprint)
        {
            if (_pollService.IsPollClosed(id))
                return Json(new { canVote = false });
            var currentUser = _orchardServices.WorkContext.CurrentUser;
            string user = currentUser == null ? "Anonymous" : currentUser.UserName;
            return Json(new { canVote = _votingService.CanVote(id, user, fingerprint) });
        }
    }
}